package com.wan.core.timer;

import com.wan.core.timer.rule.WRule;
import com.wan.core.timer.rule.WRules;
import com.wan.core.timer.task.TaskBuilder;
import com.wan.core.timer.task.TaskNode;
import com.wan.core.timer.task.WTask;

import java.time.Duration;
import java.time.LocalDateTime;

/**
 * 定时任务帮助
 * @author wwh
 * @date 2022/6/29 15:03
 */
public interface TimeHelper {
    /**
     * 添加定时任务
     */
    void addTask(TaskNode taskNode);
    /**
     * 指定时间点执行一次
     */
    default TaskNode execOnce(WTask task, LocalDateTime localDateTime){
        TaskNode taskNode = TaskBuilder.create(task)
                .executeTime(localDateTime)
                .rule(WRules.ONCE)
                .build();
        addTask(taskNode);
        return taskNode;
    }
    /**
     * 延迟时间后执行一次
     */
    default TaskNode delayOnce(WTask task, Duration duration){
        LocalDateTime executeTime = LocalDateTime.now().plus(duration);
        return execOnce(task,executeTime);
    }

    /**
     * 指定时间执行一次
     * 然后按周期执行到N次,任务一共会执行N次
     * @param rule 周期单位
     * @param period 周期
     * @param count 次数
     */
    default TaskNode repeatLimit(WTask task,WRule rule,int period,int count,LocalDateTime executeTime){
        TaskNode taskNode = TaskBuilder.create(task)
                .executeTime(executeTime)
                .rule(rule).maxTime(count)
                .period(period)
                .build();
        addTask(taskNode);
        return taskNode;
    }

    /**
     * 每隔一段时间执行一次，共N次
     * @param duration 间隔时间
     * @param count 次数 (负数代表没有次数限制)
     * @param currentExec 当前是否立即执行一次
     */
    default TaskNode repeatLimit(WTask task,Duration duration,int count,boolean currentExec){
        WRule rule = (executeTime, period) -> executeTime.plus(duration);
        LocalDateTime localDateTime = currentExec ? LocalDateTime.now(): LocalDateTime.now().plus(duration);
        return repeatLimit(task,rule,1,count,localDateTime);
    }

    /**
     * 指定时间点执行一次
     * 然后按照指定周期重复执行
     * @param rule 周期单位
     * @param period 周期
     */
    default TaskNode repeat(WTask task, WRule rule, int period,LocalDateTime localDateTime){
        return repeatLimit(task,rule,period,-1,localDateTime);
    }
}
